﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace PDX
{
    /// <summary>
    /// Metadata for a viewmodel.
    /// The purpose of this class is to be the root of all the aspects
    /// that we want to be one-to-one with a viewmodel.
    /// </summary>
    public class ViewmodelMetadata
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ViewmodelMetadata"/> class.
        /// </summary>
        /// <param name="viewmodel">The viewmodel.</param>
        public ViewmodelMetadata(object viewmodel)
        {
            this.Viewmodel = viewmodel;
            Notifier = new NotificationManager(viewmodel);
        }

        /// <summary>
        /// Gets the notifier.
        /// </summary>
        public NotificationManager Notifier { get; private set; }

        /// <summary>
        /// Gets or sets the validation adapter.
        /// </summary>
        /// <value>
        /// The validation adapter.
        /// </value>
        public IValidationAdapter ValidationAdapter { get; set; }

        /// <summary>
        /// Gets the viewmodel.
        /// </summary>
        public object Viewmodel { get; private set; }




        static System.Runtime.CompilerServices.ConditionalWeakTable<object, ViewmodelMetadata> metadata
            = new System.Runtime.CompilerServices.ConditionalWeakTable<object, ViewmodelMetadata>();

        /// <summary>
        /// Gets the <see cref="ViewmodelMetadata"/> for the specified
        /// <see cref="IPropertyModel"/>.
        /// </summary>
        /// <param name="propModel">The property model.</param>
        /// <returns></returns>
        public static ViewmodelMetadata Get(IPropertyModel propModel)
        {
            return Get(propModel.Resolution);
        }

        /// <summary>
        /// Gets the <see cref="ViewmodelMetadata"/> for the specified
        /// <see cref="IPropertyResolution"/>.
        /// </summary>
        /// <param name="resolution">The resolution.</param>
        /// <returns></returns>
        public static ViewmodelMetadata Get(IPropertyResolution resolution)
        {
            return Get(resolution.OriginalDC);
        }

        /// <summary>
        /// Gets the <see cref="ViewmodelMetadata"/> for the specified viewmodel.
        /// </summary>
        /// <param name="viewmodel">The viewmodel.</param>
        /// <returns></returns>
        public static ViewmodelMetadata Get(object viewmodel)
        {
            ViewmodelMetadata instance = null;
            if (metadata.TryGetValue(viewmodel, out instance))
            {
                return instance;
            }
            else
            {
                instance = new ViewmodelMetadata(viewmodel);
                metadata.Add(viewmodel, instance);
                return instance;
            }
        }
    }
}
